home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / share / hplip / base / tui.py < prev    next >
Text File  |  2008-10-13  |  11KB  |  357 lines

  1. # -*- coding: utf-8 -*-
  2. #
  3. # (c) Copyright 2003-2007 Hewlett-Packard Development Company, L.P.
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18. #
  19. # Author: Don Welch
  20. #
  21.  
  22. # Std Lib
  23. import sys
  24. import re
  25.  
  26. # Local
  27. from g import *
  28. import pexpect
  29. import utils
  30.  
  31. def enter_yes_no(question, default_value='y', choice_prompt=None):
  32.     if type(default_value) == type(""):
  33.         if default_value == 'y':
  34.             default_value = True
  35.         else:
  36.             default_value = False
  37.     
  38.     #assert default_value in [True, False]
  39.     
  40.     if choice_prompt is None:
  41.         if default_value:
  42.             question += " (y=yes*, n=no, q=quit) ? "
  43.         else:
  44.             question += " (y=yes, n=no*, q=quit) ? "
  45.     else:
  46.         question += choice_prompt
  47.  
  48.     while True:
  49.         user_input = raw_input(log.bold(question)).lower().strip()
  50.         
  51.         if not user_input:
  52.             return True, default_value
  53.  
  54.         if user_input == 'n':
  55.             return True, False
  56.  
  57.         if user_input == 'y':
  58.             return True, True
  59.  
  60.         if user_input in ('q', 'c'): # q -> quit, c -> cancel
  61.             return False, default_value
  62.  
  63.         log.error("Please press <enter> or enter 'y', 'n', or 'q'.")
  64.         
  65.  
  66. def enter_range(question, min_value, max_value, default_value=None):
  67.     while True:
  68.         user_input = raw_input(log.bold(question)).lower().strip()
  69.  
  70.         if not user_input:
  71.             if default_value is not None:
  72.                 return True, default_value
  73.  
  74.         if user_input == 'q':
  75.             return False, default_value
  76.  
  77.         try:
  78.             value_int = int(user_input)
  79.         except ValueError:
  80.             log.error('Please enter a number between %d and %d, or "q" to quit.' % 
  81.                 (min_value, max_value))
  82.             continue
  83.  
  84.         if value_int < min_value or value_int > max_value:
  85.             log.error('Please enter a number between %d and %d, or "q" to quit.' % 
  86.                 (min_value, max_value))
  87.             continue
  88.  
  89.         return True, value_int
  90.         
  91.  
  92. def enter_choice(question, choices, default_value=None):
  93.     if 'q' not in choices:
  94.         choices.append('q')
  95.         
  96.     while True:
  97.         user_input = raw_input(log.bold(question)).lower().strip()
  98.  
  99.         if (not user_input and default_value) or user_input == default_value:
  100.             if default_value == 'q':
  101.                 return False, default_value
  102.             else:
  103.                 return True, default_value
  104.  
  105.         #print user_input
  106.         if user_input == 'q':
  107.             return False, user_input
  108.  
  109.         if user_input in choices:
  110.             return True, user_input
  111.  
  112.         log.error("Please enter %s or press <enter> for the default of '%s'." % 
  113.             (', '.join(["'%s'" % x for x in choices]), default_value))
  114.  
  115.  
  116. def title(text):
  117.     log.info("")
  118.     log.info("")
  119.     log.info(log.bold(text))
  120.     log.info(log.bold("-"*len(text)))
  121.     
  122. def header(text):
  123.     c = len(text)
  124.     log.info("")
  125.     log.info("-"*(c+4))
  126.     log.info("| "+text+" |")
  127.     log.info("-"*(c+4))
  128.     log.info("")
  129.     
  130. def load_paper_prompt():
  131.     return continue_prompt("A page will be printed.\nPlease load plain paper into the printer.")
  132.     
  133. def load_photo_paper_prompt():
  134.     return continue_prompt("A page will be printed.\nPlease load HP Advanced Photo Paper - Glossy into the printer.")
  135.  
  136.     
  137. def continue_prompt(prompt=''):
  138.     while True:
  139.         x = raw_input(log.bold(prompt + " Press <enter> to continue or 'q' to quit: ")).lower().strip()
  140.         
  141.         if not x:
  142.             return True
  143.             
  144.         elif x == 'q':
  145.             return  False
  146.     
  147.         log.error("Please press <enter> or enter 'q' to quit.")
  148.        
  149.  
  150. def enter_regex(regex, prompt, pattern, default_value=None):
  151.     re_obj = re.compile(regex)
  152.     while True:
  153.         x = raw_input(log.bold(prompt))
  154.         
  155.         if not x and default_value is not None:
  156.             return default_value, x
  157.             
  158.         elif x == 'q':
  159.             return False, default_value
  160.             
  161.         match = re_obj.search(x)
  162.         
  163.         if not match:
  164.             log.error("Incorrect input. Please enter correct input.")
  165.             continue
  166.             
  167.         return True, x
  168.         
  169.         
  170. def ttysize():
  171.     import commands # TODO: Replace with subprocess (commands is deprecated in Python 3.0)
  172.     ln1 = commands.getoutput('stty -a').splitlines()[0]
  173.     vals = {'rows':None, 'columns':None}
  174.     for ph in ln1.split(';'):
  175.         x = ph.split()
  176.         if len(x) == 2:
  177.             vals[x[0]] = x[1]
  178.             vals[x[1]] = x[0]
  179.     return int(vals['rows']), int(vals['columns'])
  180.     
  181.     
  182. class ProgressMeter(object):
  183.     def __init__(self, prompt="Progress:"):
  184.         self.progress = 0
  185.         self.prompt = prompt
  186.         self.prev_length = 0
  187.         self.spinner = "\|/-\|/-*"
  188.         self.spinner_pos = 0
  189.         self.max_size = ttysize()[1] - len(prompt) - 25
  190.         self.update(0)
  191.         
  192.     def update(self, progress, msg=''): # progress in %
  193.         self.progress = progress
  194.         
  195.         x = self.progress * self.max_size / 100
  196.         if x > self.max_size: x = self.max_size
  197.         
  198.         if self.progress >= 100:
  199.             self.spinner_pos = 8
  200.             self.progress = 100
  201.             
  202.         sys.stdout.write("\b" * self.prev_length)
  203.         
  204.         y = "%s [%s%s%s] %d%%  %s   " % \
  205.             (self.prompt, '*'*(x-1), self.spinner[self.spinner_pos], 
  206.              ' '*(self.max_size-x), self.progress, msg)
  207.             
  208.         sys.stdout.write(y)
  209.             
  210.         sys.stdout.flush()
  211.         self.prev_length = len(y)
  212.         self.spinner_pos = (self.spinner_pos + 1) % 8
  213.         
  214.  
  215.  
  216. class Formatter(object):
  217.     def __init__(self, margin=2, header=None, min_widths=None, max_widths=None):
  218.         self.margin = margin # int
  219.         self.header = header # tuple of strings
  220.         self.rows = [] # list of tuples
  221.         self.max_widths = max_widths # tuple of ints
  222.         self.min_widths = min_widths # tuple of ints
  223.         
  224.     def add(self, row_data): # tuple of strings
  225.         self.rows.append(row_data)
  226.         
  227.     def output(self):
  228.         if self.rows:
  229.             num_cols = len(self.rows[0])
  230.             for r in self.rows:
  231.                 if len(r) != num_cols:
  232.                     log.error("Invalid number of items in row: %s" % r)
  233.                     return
  234.                     
  235.             if len(self.header) != num_cols:
  236.                 log.error("Invalid number of items in header.")
  237.                 
  238.             min_calc_widths = []
  239.             for c in self.header:
  240.                 header_parts = c.split(' ')
  241.                 max_width = 0
  242.                 for x in header_parts:
  243.                     max_width = max(max_width, len(x))
  244.                     
  245.                 min_calc_widths.append(max_width)
  246.                 
  247.             max_calc_widths = []
  248.             for x, c in enumerate(self.header):
  249.                 max_width = 0
  250.                 for r in self.rows:
  251.                     max_width = max(max_width, len(r[x]))
  252.                 
  253.                 max_calc_widths.append(max_width)
  254.                 
  255.             max_screen_width = None
  256.             
  257.             if self.max_widths is None:
  258.                 max_screen_width = ttysize()[1]
  259.                 def_max = 8*(max_screen_width/num_cols)/10
  260.                 self.max_widths = []
  261.                 for c in self.header:
  262.                     self.max_widths.append(def_max)
  263.             else:
  264.                 if len(self.max_widths) != num_cols:
  265.                     log.error("Invalid number of items in max col widths.")
  266.                     
  267.             if self.min_widths is None:
  268.                 if max_screen_width is None:
  269.                     max_screen_width = ttysize()[1]
  270.                 def_min = 4*(max_screen_width/num_cols)/10
  271.                 self.min_widths = []
  272.                 for c in self.header:
  273.                     self.min_widths.append(def_min)
  274.             else:
  275.                 if len(self.min_widths) != num_cols:
  276.                     log.error("Invalid number of items in min col widths.")
  277.             
  278.             col_widths = []
  279.             formats = []
  280.             for m1, m2, m3, m4 in zip(self.min_widths, min_calc_widths, 
  281.                                       self.max_widths, max_calc_widths):
  282.                 col_width = max(max(m1, m2), min(m3, m4))
  283.                 col_widths.append(col_width)
  284.                 formats.append({'width': col_width, 'margin': self.margin})
  285.             
  286.             formatter = utils.TextFormatter(tuple(formats))
  287.             
  288.             log.info(formatter.compose(self.header))
  289.             
  290.             sep = []
  291.             for c in col_widths:
  292.                 sep.append('-'*c)
  293.                 
  294.             log.info(formatter.compose(tuple(sep)))
  295.             
  296.             for r in self.rows:
  297.                 log.info(formatter.compose(r))
  298.                 
  299.         else:
  300.             log.error("No data rows")
  301.             
  302.  
  303.             
  304. ALIGN_LEFT = 0
  305. ALIGN_CENTER = 1
  306. ALIGN_RIGHT = 2
  307.         
  308.         
  309. def align(line, width=70, alignment=ALIGN_LEFT):
  310.     space = width - len(line)
  311.     
  312.     if alignment == ALIGN_CENTER:
  313.         return ' '*(space/2) + line + \
  314.                ' '*(space/2 + space%2)
  315.     
  316.     elif alignment == ALIGN_RIGHT:
  317.         return ' '*space + line
  318.     
  319.     else:
  320.         return line + ' '*space
  321.  
  322.  
  323. def format_paragraph(paragraph, width=None, alignment=ALIGN_LEFT):
  324.     if width is None:
  325.         width = ttysize()[1]
  326.         
  327.     result = []
  328.     #import string
  329.     words = paragraph.split() #string.split(paragraph)
  330.     try:
  331.         current, words = words[0], words[1:]
  332.     except IndexError:
  333.         return [paragraph]
  334.     
  335.     for word in words:
  336.         increment = 1 + len(word)
  337.         
  338.         if len(current) + increment > width:
  339.             result.append(align(current, width, alignment))
  340.             current = word
  341.         
  342.         else:
  343.             current = current+" "+word
  344.     
  345.     result.append(align(current, width, alignment))
  346.     #print result
  347.     return result
  348.     
  349. def show_languages():
  350.     f = Formatter()
  351.     f.header = ("Language Code", "Alternate Name(s)")
  352.     for loc, ll in supported_locales.items():
  353.         f.add((ll[0], ', '.join(ll[1:])))
  354.  
  355.     f.output()
  356.  
  357.